﻿#ifndef IPLUGINOPERATOR_H
#define IPLUGINOPERATOR_H

#include <QObject>
#include <QDomDocument>
#include <QDialog>
#include <QMap>
#include <QList>

#include <Interface_Global.h>
#include "FlowTree.h"
#include "IPluginParam.h"
#include "PluginDesc.h"
#include "FlowCellParam.h"

class PluginContainerWidget;
namespace CVV
{

namespace Interface
{

class IPluginDialog;

class INTERFACE_EXPORT IPluginOperator : public QObject
{
    Q_OBJECT
public:
    explicit IPluginOperator(QObject *parent = nullptr);
    virtual ~IPluginOperator();
    /**
     * @brief createInstance 创建流程单元对象
     * @param flowId 流程Id
     * @param cellId 流程单元Id
     * @return
     */
    virtual bool createFlowCell(const QString &pluginCode, const QString &flowId, const QString &cellId, const QString &cellTitle) = 0;

    /**
     * @brief init 打开流程时候，先内存构建Dom树，根据Dom 逐步初始化流程单元
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    bool init(const QString &flowId, const QString& cellId, const QDomElement &cellDom);

    /**
     * @brief Run 根据内存构建Dom树中执行流程单元
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    bool run(const QString &flowId, const QString &cellId);

    /**
     * @brief deleteInstance 移除流程单元对象
     * @param flowId 流程Id
     * @param cellId 流程单元Id
     */
     bool  removeFlowCellDialog(const QString &flowId, const QString &cellId) ;

    /**
     * @brief removeFlowDialog
     * @param flowId
     */
     bool removeFlowDialog(const QString &flowId);

    /**
     * @brief flowCellDialogs 流程单元对象存储
     * @return
     */
     QMap<QString,QMap<QString, std::shared_ptr<IPluginDialog>>> flowCellDialogs() const;
     void setflowCellDialogs(const QMap<QString, QMap<QString, std::shared_ptr<IPluginDialog>>> &value);

     /**
     * @brief updateFlowTree
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @param flowTree 流程树Map key 单元ID
     */
    void updateFlowTree(const QString &flowId, const QString &cellId, const QMap<QString, FlowTree> &flowTree);

    /**
     * @brief Run 根据内存构建Dom树中执行流程单元
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    static bool run(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief init
     * @param pluginCode
     * @param flowId
     * @param cellId
     * @param cellDom
     * @return
     */
    static bool init(const QString &pluginCode, const QString &flowId, const QString& cellId, const QDomElement &cellDom);

    /**
     * @brief deleteInstance 移除流程单元对象
     * @param flowId 流程Id
     * @param cellId 流程单元Id
     */
    static bool  removeFlowCellDialog(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief removeFlowDialog 移除该流程上所有的单元插件
     * @param flowId
     */
    static bool removeAllFlowDialog(const QString &flowId);

    /**
     * @brief removeAlgorithmParamv删除指定的算法参数
     * @param pluginCode
     * @param flowId
     * @param cellId
     * @return
     */
    static void removeAlgorithmParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief updateFlowTree
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @param flowTree 流程树Map key 单元ID
     */
    static bool updateFlowTree(const QString &pluginCode,
                               const QString &flowId,
                               const QString &cellId,
                               const QMap<QString,FlowTree> &flowTree);

    /**
     * @brief getPluginDesc 获取插件描述信息
     * @return
     */
    static QList<PluginDesc> getPluginDescList();

    /**
     * @brief getFlowCellParam 获取插件参数变量数据列表
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    static QList<FlowCellParam>  getFlowCellParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief getFlowCellAlgorithmParam
     * @param pluginCode
     * @param flowId
     * @param cellId
     * @return
     */
    static QList<FlowCellParam> getFlowCellAlgorithmParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief getFlowParam
     * @param pluginCode
     * @param flowId
     * @param cellId
     * @return
     */
    static QMap<QString, QList<FlowCellParam>> getFlowParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief getPluginParam 获取当前流程单元参数
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    static IPluginParam  getPluginParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief resetDialogParamRunState 重置dialog参数运行状态值
     * @param pluginCode 插件Code
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    static void resetDialogParamRunState(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief showFlowCellDialog
     * @param pluginCode 插件Code
     * @param flowId 流程Id
     * @param cellId 单元Id
     * @return
     */
    static IPluginParam showFlowCellDialog(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief createFlowCellDialog
     * @param pluginCode
     * @param flowId
     * @param cellId
     * @param cellTitle
     * @param lstDefectPinYinCode
     * @param subflowFileName 子流程文件名
     * @param bIsExamples 是否是案例方案
     * @return
     */
    static QList<FlowCellParam> createFlowCellDialog(const QString &pluginCode,
                                                     const QString &flowId,
                                                     const QString &cellId,
                                                     const QString &cellTitle,
                                                     const QStringList &lstDefectPinYinCode = QStringList(),
                                                     const QString &subflowFileName = QString(),
                                                     bool bIsExamples = false);

    static QList<FlowCellParam> updateSubProcessFilePath(const QString flowId, const QString cellId, const QString filePath, const QString title);

    static std::shared_ptr<IPluginDialog> getFlowCellDialog(const QString &pluginCode, const QString &flowId, const QString &cellId);
    void changeLanguage(QString local);

    /**
     * @brief createAlgorithmParam 创建算法参数
     * @param pluginCode
     * @param flowId
     * @param cellId
     */
    static void createAlgorithmParam(const QString &pluginCode, const QString &flowId, const QString &cellId);

    /**
     * @brief getFlowTreeParams 获取指定流程的所有参数
     * @param flowId
     * @return
     */
    static QHash<QString, QList<FlowCellParam>> getFlowTreeParams(const QString &flowId);

    //by cui.qingcheng
    /**
      * @brief 设置插件为模型数据
      */
    static bool setIPluginisModelData(const QString &pluginCode, const QString &flowId, const QString &cellId, bool isModel);

    /**
     * @brief setSubprocessInputParam 子流程参数
     * @param flowId 子流程id
     * @param hashData 子流程输入参数
     * @param mapParamValue 子流程输入参数值
     */
    static void setSubprocessInputParam(const QString &flowId,
                                        const QHash<QString, QList<FlowCellParam>> &hashData,
                                        const QMap<QString, QVariant> &mapParamValue);

protected:
    /**
     * @brief m_FlowCellDialogs 流程单元对话框
     * key1 流程key  key2 单元Id
     */
    QMap<QString,QMap<QString, std::shared_ptr<IPluginDialog>>> m_flowCellDialogs;

private:
    static QString s_localName;

protected:
   bool createDialog(const QString &flowId, const QString &cellId, std::shared_ptr<IPluginDialog> dialog);

private:
   /**
    * @brief initCellParam 单元插件参数
    * @param domEle
    * @return
    */
   bool initCellParam(const QDomElement &domEle, const QString &flowId, const QString &cellId, bool isModelData = false);

   /**
    * @brief initCellAlgorithmParam 单元插件算法参数
    * @param domEle
    * @return
    */
   bool initCellAlgorithmParam(const QDomElement &domEle, const QString &flowId, const QString &cellId);

   /**
    * @brief parserCellParamChildNode 流程插件参数子参数节点
    * @param node
    * @param pluginVariantMap
    * @return
    */
   bool parserCellParamChildNode(const QDomNode &node, QMap<QString, QVariant> &pluginVariantMap);

   /**
    * @brief parserCellAlgorithmParamChildNode 算法插件参数子参数节点
    * @param node
    * @param pluginVariantMap
    * @return
    */
   bool parserCellAlgorithmParamChildNode(const QDomNode &node, QMap<QString, QVariant> &pluginVariantMap);
};

}

}
#endif // IPLUGINOPERATOR_H
